package com.neusoft.bizcore.activiti.controller;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.neusoft.bizcore.activiti.dto.ProcessBpmnDTO;
import com.neusoft.bizcore.activiti.dto.ProcessNodeDTO;
import com.neusoft.bizcore.activiti.service.MoldDefinitionService;
import com.neusoft.bizcore.web.dto.result.ResultDTO;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

@Api(tags = "工作流模板定义BPMN管理")
@RestController
@Slf4j
@RequestMapping(value = "/api/w/act/models")
public class ActMoldDefinitionController {

    @Autowired
    private MoldDefinitionService moldDefinitionService;

    @ApiOperation("删除流程定义")
    @DeleteMapping("/{processKey}")
    public ResultDTO<Void> delete(@PathVariable final String processKey) {
        this.moldDefinitionService.delete(processKey);
        return ResultDTO.success();
    }

    @ApiOperation("获取BPMN详细")
    @GetMapping("bpmn/{id}")
    public ResultDTO<ProcessBpmnDTO> details(@PathVariable final String id) {
        final ProcessBpmnDTO result = this.moldDefinitionService.details(id);
        return ResultDTO.success(result);
    }

    @ApiOperation("创建BPMN")
    @PostMapping("bpmn")
    public ResultDTO<Void> create(@RequestBody final ProcessBpmnDTO dto) {
        this.moldDefinitionService.create(dto);
        return ResultDTO.success();
    }

    @ApiOperation("获取开始节点信息")
    @GetMapping("/startform/{type}")
    public ResultDTO<ProcessNodeDTO> startForm(@PathVariable final String type) {
        final ProcessNodeDTO result = this.moldDefinitionService.getStartForm(type);
        return ResultDTO.success(result);
    }

    @ApiOperation("导出流程图的xml定义文件")
    @GetMapping(value = "/export/{code}")
    public void download(@PathVariable final String code, final HttpServletResponse response) {

        final ProcessBpmnDTO result = this.moldDefinitionService.details(code);
        OutputStream out = null;
        try {
            out = response.getOutputStream();
            response.setContentType("text/plain");
            response.setHeader("Content-disposition",
                    String.format("attachment; filename=%s",
                            URLEncoder.encode(result.getName() + ".bpmn", "UTF-8")));
            final BufferedOutputStream buff = new BufferedOutputStream(out);
            buff.write(result.getXmlContent().getBytes("UTF-8"));
            buff.flush();
            buff.close();
            out.flush();
        } catch (final Exception e) {
            ActMoldDefinitionController.log.error("导出流程图失败", e);
        } finally {
            try {
                out.close();
            } catch (final IOException e) {
                ActMoldDefinitionController.log.error("导出流程图关闭流失败", e);
            }
        }
    }

    @ApiOperation("导入流程模板定义")
    @PostMapping("/import/{code}")
    public void upload(@RequestParam("file") final MultipartFile file, @PathVariable final String code) {
        try {
            final InputStream fileStream = file.getInputStream();
            this.moldDefinitionService.upload(code, fileStream);

        } catch (final IOException e) {
            ActMoldDefinitionController.log.error(e.getMessage(), e);
        }
    }
}
